package learn.ch1.wn;

/**
 * @Description todo
 * @Author yusj
 * @Date 2021/12/14
 * @Version 1.0
 */
public class Express {
    private String CITY="Shanghai";
    private Integer site=0;
    private boolean isInterrupted=Thread.currentThread().isInterrupted();

    public synchronized void setCITY(String city){
        this.CITY=city;
        notify();
    }

    public synchronized String getCITY() {
        while("Shanghai".equals(CITY)&&!isInterrupted){
            try {
                wait();
                System.out.println(Thread.currentThread().getName()+" notifed");
            } catch (InterruptedException e) {

            }
        }
        System.out.println(Thread.currentThread().getName()+" getCITY "+CITY);
        return CITY;
    }

    public synchronized void setSite(int site){
        this.site=site;
        notifyAll();
    }

    public synchronized Integer getSite(){
        while(site<=100&&!isInterrupted){
            try {
                wait();
                System.out.println(Thread.currentThread().getName()+" notifed");
            } catch (InterruptedException e) {
                break;
            }
        }
        System.out.println(Thread.currentThread().getName()+" getSite "+site);
        return site;
    }


    /**
     * 线程间的等待和通知机制：
     *
     * Object.
     * wait()
     * notify()/notifyAll()
     *
     * 等待和通知的标准范式：
     * 等待方：
     *  1.获取对象的锁
     *  2.循环里面判定   条件是否满足。不满足  调用wait().
     *  3.条件满足，执行业务逻辑。
     *
     *
     * 通知方：
     * 1.获得对象的锁。
     * 2.改变条件。
     * 3.通知所有wait()  的线程。
     *
     * 尽量使用：notifyAll()
     *
     * 那么notify   会通知谁呢？   会在多个wait()  里面挑一个然后notify   ，通常都会通知等待时间最长的。
     *
     */
    public static void main(String[] args ){
        Express express=new Express();

        Thread th03=new Thread(express::getSite,"th03");
        th03.start();
        new Thread(express::getCITY,"th01").start();
        new Thread(express::getCITY,"th02").start();

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        express.setCITY("Haerbin");

    }

}
